home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 May: Tool Chest / Developer CD Series May 1996 (Tool Chest) (Apple Computer) (1996).iso / Sample Code / Snippets / QuickDraw / NewCCursor / NewCCursor.c next >
Encoding:
C/C++ Source or Header  |  1995-06-12  |  9.8 KB  |  447 lines  |  [TEXT/MPS ]

  1. /*******************************************/
  2. /*                                           */
  3. /*    File:        NewCCursor.c               */
  4. /*                                           */
  5. /*    Program:    NewCCursor                   */
  6. /*                                           */
  7. /*    By:            Jason Hodges Harris           */
  8. /*                                           */
  9. /*    Version:    1.0.1                       */
  10. /*                                           */
  11. /*******************************************/
  12.  
  13. //    This Code snippet creates from scratch both Black & White 'CURS'
  14. //  and color 'crsr' Cursors from PICT resources.
  15.  
  16.  
  17. // Mac Toolbox headers
  18.  
  19. #ifndef __DESK__
  20. #include <Desk.h>
  21. #endif
  22.  
  23. #ifndef __DIALOGS__
  24. #include <Dialogs.h>
  25. #endif
  26.  
  27. #ifndef __DISKINIT__
  28. #include <DiskInit.h>
  29. #endif
  30.  
  31. #ifndef __EVENTS__
  32. #include <Events.h>
  33. #endif
  34.  
  35. #ifndef __FILES__
  36. #include <Files.h>
  37. #endif
  38.  
  39. #ifndef __FONTS__
  40. #include <Fonts.h>
  41. #endif
  42.  
  43. #ifndef __MEMORY__
  44. #include <Memory.h>
  45. #endif
  46.  
  47. #ifndef __MENUS__
  48. #include <Menus.h>
  49. #endif
  50.  
  51. #ifndef __QDOFFSCREEN__
  52. #include <QDOffscreen.h>
  53. #endif
  54.  
  55. #ifndef __RESOURCES__
  56. #include <Resources.h>
  57. #endif
  58.  
  59. #ifndef __SCRIPT__
  60. #include <Script.h>
  61. #endif
  62.  
  63. #ifndef __SEGLOAD__
  64. #include <SegLoad.h>
  65. #endif
  66.  
  67. #ifndef __STANDARDFILE__
  68. #include <StandardFile.h>
  69. #endif
  70.  
  71. #ifndef __STRING__
  72. #include <String.H>
  73. #endif
  74.  
  75. #ifndef __TEXTEDIT__
  76. #include <TextEdit.h>
  77. #endif
  78.  
  79. #ifndef __TEXTUTILS__
  80. #include <TextUtils.h>
  81. #endif
  82.  
  83. #ifndef __TOOLUTILS__
  84. #include <ToolUtils.h>
  85. #endif
  86.  
  87. #ifndef __TYPES__
  88. #include <Types.h>
  89. #endif
  90.  
  91. #ifndef __WINDOWS__
  92. #include <Windows.h>
  93. #endif
  94.  
  95.  
  96. #define HiWrd(aLong)    (((aLong) >> 16) & 0xFFFF)
  97. #define LoWrd(aLong)    ((aLong) & 0xFFFF)
  98.  
  99.  
  100. // menu defs
  101.  
  102. #define    mApple        128
  103. #define    iAbout        1
  104.  
  105. #define    mFile        129
  106. #define    iQuit        1
  107.  
  108. #define mTest        130
  109. #define    iBWCursor    1
  110. #define    iCCursor    2
  111.  
  112.  
  113. // Global variables
  114.  
  115. CCrsrHandle        gNewCCursorHndl = nil;
  116. Cursor            gNewCursor;
  117. Boolean         gQuitFlag = false,
  118.                 gCustomCursor = false,
  119.                 gCursorDepth = 0;
  120.  
  121.  
  122. // function prototypes
  123.  
  124. void    InitToolbox(void);
  125. void    MainEventLoop(void);
  126. void    HandleKeyPress(EventRecord *myEvent); 
  127. void    HandleMenuCommand(long menuResult);
  128. void    CreateCursor(short depth);
  129.  
  130.  
  131.  
  132. // main program function
  133.  
  134. int main()
  135. {
  136.     InitToolbox() ;
  137.     MainEventLoop();
  138.     return 0;
  139. }
  140.  
  141.  
  142.  
  143. // toolbox initialisation
  144.  
  145. void InitToolbox()
  146. {
  147.     OSErr         retCode;
  148.     long         gestResponse;
  149.     Handle        menuBar = nil;
  150.     EventRecord myEvent;
  151.     short        count;
  152.  
  153.  
  154.     MaxApplZone();
  155.     InitGraf((Ptr) &qd.thePort);
  156.     InitFonts();
  157.     InitWindows();
  158.     InitMenus();
  159.     TEInit();
  160.     InitDialogs(0L);
  161.     InitCursor();
  162.  
  163.     menuBar = GetNewMBar(128);
  164.     if (menuBar == nil)
  165.          ExitToShell();
  166.     SetMenuBar(menuBar);
  167.     DisposHandle(menuBar);
  168.     AddResMenu(GetMHandle(mApple), 'DRVR');    // Add DA names to Apple menu, ID 128
  169.     DrawMenuBar();
  170. }
  171.  
  172.  
  173. // Event processing
  174.  
  175. void MainEventLoop()
  176. {
  177.     EventRecord     myEvent;
  178.     WindowPtr       window;
  179.     short           thePart;
  180.     Rect            screenRect;
  181.     Point            aPoint = {100, 100};
  182.     GrafPtr            oldPort ;
  183.  
  184.     while( !gQuitFlag )
  185.     {
  186.         if (WaitNextEvent( everyEvent, &myEvent, 0, nil ))
  187.         {
  188.             switch (myEvent.what)
  189.             {
  190.                 case mouseDown:
  191.                     thePart = FindWindow( myEvent.where, &window );
  192.                     switch( thePart )
  193.                     {
  194.                         case inMenuBar: 
  195.                             HandleMenuCommand(MenuSelect(myEvent.where));
  196.                         break;
  197.                         
  198.                         case inDrag:
  199.                         break ;
  200.                     
  201.                         case inContent:
  202.                         break ;
  203.                     
  204.                         case inGoAway:
  205.                         break ;
  206.                             
  207.                         default:
  208.                         break ;
  209.                     }
  210.                     break ;
  211.                         
  212.                 case updateEvt:
  213.                 break ;
  214.                     
  215.                 case keyDown:
  216.  
  217.                 case autoKey:
  218.                     HandleKeyPress(&myEvent);
  219.                 break;
  220.                     
  221.                 case diskEvt:
  222.                     if ( HiWrd(myEvent.message) != noErr ) 
  223.                         (void) DIBadMount(aPoint, myEvent.message);
  224.                 break;
  225.                 case osEvt:
  226.                 case activateEvt:
  227.                     // restore custom cursor on application activate event
  228.                     if (myEvent.message>>24 == resumeFlag)
  229.                     {
  230.                         if (gCustomCursor && gCursorDepth == 1)
  231.                             SetCursor(&gNewCursor);
  232.                         else if (gCustomCursor && gCursorDepth == 8)
  233.                             SetCCursor(gNewCCursorHndl);
  234.                     }
  235.                 break;
  236.             }
  237.         }
  238.     }
  239. }
  240.  
  241.  
  242. void HandleKeyPress(EventRecord *myEvent)
  243. {
  244.     char    key;
  245.     long    lByteCnt ;
  246.  
  247.     key = myEvent->message & charCodeMask;
  248.     
  249.     if ( myEvent->modifiers & cmdKey )    //    Cmd key down?
  250.     {
  251.         HandleMenuCommand(MenuKey(key));
  252.     } 
  253. }
  254.  
  255.  
  256.  
  257. // process menubar commands
  258.  
  259. void HandleMenuCommand(long menuResult)
  260. {
  261.     short            menuID;
  262.     short            menuItem;
  263.     Str255            daName;
  264.     DialogPtr        theDialog ; 
  265.     short            itemHit ;
  266.     Rect            cursorRect = {0,0,16,16};
  267.  
  268.     menuID = HiWrd(menuResult);
  269.     menuItem = LoWrd(menuResult);
  270.     switch ( menuID )
  271.     {
  272.         case mApple:
  273.             switch ( menuItem )
  274.             {
  275.                 case iAbout:
  276.                     theDialog = GetNewDialog ( 128, nil, (WindowPtr)-1 );
  277.                     do {
  278.                         ModalDialog ( nil, &itemHit );
  279.                     } while( itemHit != ok ) ;
  280.                     DisposDialog ( theDialog );
  281.                 break;
  282.                     
  283.                 default:
  284.                     GetItem(GetMHandle(mApple), menuItem, daName);
  285.                     (void) OpenDeskAcc(daName);
  286.                 break;
  287.             }
  288.             break;
  289.         case mFile:
  290.             switch ( menuItem )
  291.             {
  292.                 case iQuit:
  293.                     gQuitFlag = true;
  294.                 break;
  295.             }
  296.             break;
  297.         case mTest:    
  298.             switch (menuItem)
  299.             {
  300.                 case iBWCursor:
  301.                     CreateCursor(1);        // create 1 bit cursor from PICT rsrc
  302.                 break ;
  303.                 case iCCursor:
  304.                     CreateCursor(8);        // create 8 bit cursor from PICT rsrc
  305.                 break;
  306.             }
  307.             break;
  308.     }
  309.     HiliteMenu(0);        // Unhighlight whatever MenuSelect or MenuKey hilited
  310. }
  311.  
  312.  
  313. // function to create from scratch either a 1 bit CURS or an 8 bit crsr 
  314. // See Inside Macintosh, "Imaging With QuickDraw", Ch 8 Cursor Utilities,
  315. // for an in depth explanation of the crsr and CURS structures.
  316.  
  317. void    CreateCursor(short depth)
  318. {
  319.     PixMapHandle    myPixmap = nil;
  320.     GDHandle        oldDevice = nil;
  321.     PicHandle        cursorPict = nil;
  322.     GWorldPtr        myGWorldPtr = nil,
  323.                     oldPort = nil;
  324.     Ptr                cursorBaseAddr = nil;
  325.     QDErr            myError;
  326.     Rect            cursorRect = {0,0,16,16};
  327.     short            pixRowbytes,
  328.                     count,
  329.                     count2,
  330.                     maskInfo,
  331.                     tempInfo;
  332.     char            myAddrMode = true32b;
  333.     
  334.     GetGWorld(&oldPort,&oldDevice);
  335.     gCursorDepth = depth;
  336.     switch (depth)
  337.     {
  338.         case 1:
  339.             cursorPict=GetPicture(1000);    // 16*16 1 bit B/W PICT to be used as cursor
  340.         break;
  341.         case 8:
  342.             cursorPict=GetPicture(1001);    //16*16 8 bit color PICT to be used as cursor
  343.         break;
  344.     }
  345.     if (cursorPict==nil)
  346.     {
  347.         // handle GWorld creation errors here
  348.         DebugStr("\pFailed to get PICT rsrc");
  349.         return;
  350.     }
  351.     // create GWorld to temp hold of PICT rsrc for conversion.
  352.     myError=NewGWorld(&myGWorldPtr,depth,&cursorRect,nil,nil,0);
  353.     if (myError)
  354.     {
  355.         // handle GWorld creation errors here
  356.         DebugStr("\pFailed to allocate GWorld.");
  357.         return;
  358.     }
  359.     myPixmap = GetGWorldPixMap(myGWorldPtr);    // get GWorld PixMap
  360.     SwapMMUMode (&myAddrMode);                    // switch to 32 bit mode
  361.     LockPixels(myPixmap);                        // lock down PixMap
  362.     SetGWorld(myGWorldPtr,nil);                    // set port to GWorld 
  363.     HLockHi((Handle)cursorPict);
  364.     DrawPicture(cursorPict,&cursorRect);        // draw PICT to GWorld
  365.     HUnlock((Handle)cursorPict);
  366.     ReleaseResource((Handle)cursorPict);        // release PICT as no longer required
  367.     GetGWorld(&oldPort,&oldDevice);                // reset port
  368.     pixRowbytes    = (**myPixmap).rowBytes & 0x3FFF;    // get GWorld PixMap rowBytes
  369.     cursorBaseAddr = (**myPixmap).baseAddr;        // get GWorld PixMap base addr
  370.     switch (depth)
  371.     {
  372.         case 1:                                    // B/W Cursor
  373.             for (count=0;count<16;count++)
  374.             {
  375.                 memcpy (&gNewCursor.data[count],cursorBaseAddr,2);    // copy pict data into cursor struct
  376.                 gNewCursor.mask[count] = gNewCursor.data[count];    // mask = data 
  377.                 cursorBaseAddr+=pixRowbytes;
  378.             }
  379.             gNewCursor.hotSpot.v = 15;
  380.             gNewCursor.hotSpot.h = 0;
  381.             gCustomCursor = true;
  382.             SetCursor(&gNewCursor);
  383.         break;
  384.         case 8:                                            // Color Cursor
  385.             // create new Handle to hold Color Table
  386.             if (gNewCCursorHndl !=nil)
  387.             {
  388.                 // dispose of old handles if already allocated. Stops memory leaks.
  389.                 DisposeHandle((Handle)(**gNewCCursorHndl).crsrData);
  390.                 DisposeHandle((Handle)(**(**gNewCCursorHndl).crsrMap).pmTable);
  391.                 DisposeHandle((Handle)(**gNewCCursorHndl).crsrMap);
  392.                 DisposeHandle((Handle)gNewCCursorHndl);
  393.             }
  394.             gNewCCursorHndl = (CCrsrHandle) NewHandle(sizeof(CCrsr));    // create crsr handle
  395.             (**gNewCCursorHndl).crsrType = 0x8001;    // color cursor
  396.             (**gNewCCursorHndl).crsrMap = NewPixMap();
  397.             (**(**gNewCCursorHndl).crsrMap).bounds = cursorRect;
  398.             (**(**gNewCCursorHndl).crsrMap).rowBytes = 16;        // 16 (8 bits deep) pixels wide
  399.             (**(**gNewCCursorHndl).crsrMap).pixelSize = 8;        // 8 bits deep    
  400.             SetHandleSize((Handle)(**(**gNewCCursorHndl).crsrMap).pmTable,(sizeof(ColorTable)+(sizeof(ColorSpec)*256)));
  401.  
  402.             // copy color table from Pict GWorld to Color Cursor
  403.             HLock((Handle)(**(**gNewCCursorHndl).crsrMap).pmTable);
  404.             HLock((Handle)(**myPixmap).pmTable);
  405.             BlockMove((*(**myPixmap).pmTable),
  406.                 (*(**(**gNewCCursorHndl).crsrMap).pmTable),
  407.                 (sizeof(ColorTable)+(sizeof(ColorSpec)*256)));
  408.             HUnlock((Handle)(**(**gNewCCursorHndl).crsrMap).pmTable);
  409.             HUnlock((Handle)(**myPixmap).pmTable);
  410.             CTabChanged((**(**gNewCCursorHndl).crsrMap).pmTable);
  411.             (**gNewCCursorHndl).crsrData = NewHandle(256);
  412.             HLock((**gNewCCursorHndl).crsrData);
  413.  
  414.             // copy data from PICT into crsr to build CCursor 
  415.             for (count=0;count<16;count++)
  416.             {
  417.                 memcpy ((*(**gNewCCursorHndl).crsrData)+(16*count),cursorBaseAddr,16);    // get data type
  418.                 cursorBaseAddr+=pixRowbytes;
  419.             }
  420.             (**gNewCCursorHndl).crsrXValid = 0;    // Cursor to be re expanded
  421.             (**gNewCCursorHndl).crsrXHandle = 0; // reserved
  422.  
  423.             // create crsr mask
  424.             for (count=0;count<16;count++)
  425.             {
  426.                 maskInfo=0;
  427.                 for (count2=0;count2<16;count2++)
  428.                 {
  429.                     tempInfo = *((*(**gNewCCursorHndl).crsrData)+(16*count+count2));
  430.                     if (tempInfo)    // if image byte has value mask relevant bit
  431.                         maskInfo = maskInfo | 1<<(15-count2);
  432.                 }
  433.                 (**gNewCCursorHndl).crsrMask[count] = maskInfo;    // place current line of mask into struct
  434.             }
  435.             HUnlock((**gNewCCursorHndl).crsrData);
  436.             (**gNewCCursorHndl).crsrHotSpot.v = 15;
  437.             (**gNewCCursorHndl).crsrHotSpot.h = 0;
  438.             (**gNewCCursorHndl).crsrXTable = 0;    // reserved
  439.             gCustomCursor = true;
  440.             SetCCursor(gNewCCursorHndl);
  441.         break;
  442.     }
  443.     UnlockPixels(myPixmap);
  444.     DisposeGWorld(myGWorldPtr);        // Clean up deallocation of GWorld
  445.     SwapMMUMode (&myAddrMode);        // restore addressing mode
  446. }
  447.